/*
 * zipfile.cpp
 *
 *  Created on: 2021年3月3日
 *      Author: Admin
 */
#include "zipfile.h"
#include "utils/Log.h"

#include "string.h"
#include "zkdisplay.h"
#include "minizip/unzip.h"
#include <sys/types.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <time.h>

#define STB_IMAGE_IMPLEMENTATION
#define STB_IMAGE_STATIC
#define STBI_NO_PSD
#define STBI_NO_TGA
#define STBI_NO_GIF
#define STBI_NO_HDR
#define STBI_NO_PIC
#define STBI_NO_PNM
#include "stb_image.h"

#define DIE_DELIMTER '/'
#define MAX_FILENAME 512


int str_ends_with(const char * str, const char * suffix) {

  if( str == NULL || suffix == NULL )
    return 0;

  size_t str_len = strlen(str);
  size_t suffix_len = strlen(suffix);

  if(suffix_len > str_len)
    return 0;

  return 0 == strncmp(str + str_len - suffix_len, suffix, suffix_len);
}
void writefile(const char* filename,unsigned char* pdata,uint32_t len ) {
	bool ret= true;
	FILE* m_fp = fopen(filename, "w");
	if (m_fp != NULL) {
		fwrite(pdata,1,len, m_fp);
		fclose(m_fp);

	}else{
		LOGD(" file error!!!");
	}
	return ;
}
bool showZipPreView(const char* fileName,ZKTextView* textView) {
    LOGD(" ProgressPrint:%s !!!\n",fileName);
    int width = 0, height = 0, depth = 0;

    const char* fn = fileName;

	textView->setText("生成中……");
    unzFile zipfile = unzOpen(fn);
   	if (zipfile == NULL)
   	{
   		LOGD("%s: not found\n", fn);
   		textView->setText("文件错误");
   		return false;
   	}

   	// Get info about the zip file
   	unz_global_info global_info;
   	if (unzGetGlobalInfo(zipfile, &global_info) != UNZ_OK)
   	{
   		LOGD("could not read zip file global info\n");
   		unzClose(zipfile);
   		textView->setText("文件错误");
   		return false;
   	}
   	bool bSet =false;
   	// Loop to extract all files
   	for (int i = 0; i < global_info.number_entry; ++i)
   	{
   		// Get info about current file.
   		unz_file_info file_info;
   		char filename[MAX_FILENAME];
   		if (unzGetCurrentFileInfo(zipfile, &file_info, filename, MAX_FILENAME, NULL, 0, NULL, 0) != UNZ_OK)
   		{
   			LOGD("could not read file info\n");
   			unzClose(zipfile);
   			return false;
   		}

   		LOGD("file[%s ]filesize cs:%d, us:%d\n",filename, file_info.compressed_size, file_info.uncompressed_size);

   		if(strcmp(filename,"preview_cropping.png") == 0){
   			LOGD("file:%s\n", filename);
			if (unzOpenCurrentFile(zipfile) != UNZ_OK)
			{
				LOGD("could not open file: %s\n", filename);
				unzClose(zipfile);
				return false;
			}

			LOGD("extract file:%s\n", filename);

			int error = UNZ_OK;
			unsigned char* read_buf = (unsigned char*)malloc(file_info.uncompressed_size);
			error = unzReadCurrentFile(zipfile, read_buf, file_info.uncompressed_size);
			if (error < 0)
			{
				LOGD("error %d\n", error);
				unzCloseCurrentFile(zipfile);
				unzClose(zipfile);
				free(read_buf);
				return false;
			}
			writefile("/mnt/extsd/priview.png",read_buf, file_info.uncompressed_size);
			textView->setBackgroundPic("/mnt/extsd/priview.png");
			textView->setText("");
			bSet = true;
			//uint8_t *pData = stbi_load_from_memory(read_buf, file_info.uncompressed_size, &width, &height, &depth, 0);
			free(read_buf);

			LOGD("width %d, height %d, depth %d\n", width, height, depth);
   		}

   		unzCloseCurrentFile(zipfile);
   		// Go the the next entry listed in the zip file.
   		if ((i+1) < global_info.number_entry)
   		{
   			if (unzGoToNextFile(zipfile) != UNZ_OK)
   			{
   				LOGD("cound not read next file\n");
   				unzClose(zipfile);
   				return false;
   			}
   		}
   	}
   	unzClose(zipfile);
   	if(!bSet){
   		textView->setText("没有priview.png");
   	}
    return 1;
}
bool showZipToMonoDisplay(const char* zFile,const char* bmpfile) {
    LOGD(" ProgressPrint:%s[%s] !!!\n",zFile,bmpfile);
    int width = 0, height = 0, depth = 0;

    const char* fn = zFile;
    unzFile zipfile = unzOpen(fn);
   	if (zipfile == NULL)
   	{
   		LOGD("%s: not found\n", fn);
   		return false;
   	}

   	// Get info about the zip file
   	unz_global_info global_info;
   	if (unzGetGlobalInfo(zipfile, &global_info) != UNZ_OK)
   	{
   		LOGD("could not read zip file global info\n");
   		unzClose(zipfile);
   		return false;
   	}
   	bool bSet =false;
   	// Loop to extract all files
   	for (int i = 0; i < global_info.number_entry; ++i)
   	{
   		// Get info about current file.
   		unz_file_info file_info;
   		char filename[MAX_FILENAME];
   		if (unzGetCurrentFileInfo(zipfile, &file_info, filename, MAX_FILENAME, NULL, 0, NULL, 0) != UNZ_OK)
   		{
   			LOGD("could not read file info\n");
   			unzClose(zipfile);
   			return false;
   		}

   		LOGD("file[%s ]filesize cs:%d, us:%d\n",filename, file_info.compressed_size, file_info.uncompressed_size);

   		if(strcmp(filename,bmpfile) == 0){
   			LOGD("file:%s\n", filename);
			if (unzOpenCurrentFile(zipfile) != UNZ_OK)
			{
				LOGD("could not open file: %s\n", filename);
				unzClose(zipfile);
				return false;
			}

			LOGD("extract file:%s\n", filename);

			int error = UNZ_OK;
			unsigned char* read_buf = (unsigned char*)malloc(file_info.uncompressed_size);
			error = unzReadCurrentFile(zipfile, read_buf, file_info.uncompressed_size);
			if (error < 0)
			{
				LOGD("error %d\n", error);
				unzCloseCurrentFile(zipfile);
				unzClose(zipfile);
				free(read_buf);
				return false;
			}

			uint8_t *pData = stbi_load_from_memory(read_buf, file_info.uncompressed_size, &width, &height, &depth, 0);
			free(read_buf);

			if (pData) {
				LOGD("width %d, height %d, depth %d\n", width, height, depth);
				uint8_t datatemp;
				for(int h =0;h < height;h++){
					uint8_t *lineData = &pData[h*width];
					for(int w = 0;w < width;w+=3){
						datatemp = lineData[w];
						lineData[w] = lineData[w+2];
						//lineData[w+1] = lineData[w+2];
						lineData[w+2] = datatemp;
					}
				}
				zk_display_draw(pData, width/3, height, 3);
				stbi_image_free(pData);

			}
			bSet = true;
   		}

   		unzCloseCurrentFile(zipfile);
   		if(bSet) break;
   		// Go the the next entry listed in the zip file.
   		if ((i+1) < global_info.number_entry)
   		{
   			if (unzGoToNextFile(zipfile) != UNZ_OK)
   			{
   				LOGD("cound not read next file\n");
   				unzClose(zipfile);
   				return false;
   			}
   		}
   	}
   	unzClose(zipfile);
    return bSet;
}
bool ProgressPrint(const char* fileName) {
    LOGD(" ProgressPrint:%s !!!\n",ProgressPrint);
    int width = 0, height = 0, depth = 0;

    const char* fn = fileName;

    unzFile zipfile = unzOpen(fn);
   	if (zipfile == NULL)
   	{
   		LOGD("%s: not found\n", fn);
   		return false;
   	}

   	// Get info about the zip file
   	unz_global_info global_info;
   	if (unzGetGlobalInfo(zipfile, &global_info) != UNZ_OK)
   	{
   		LOGD("could not read zip file global info\n");
   		unzClose(zipfile);
   		return false;
   	}
   	zk_display_init();
   	// Loop to extract all files
   	for (int i = 0; i < global_info.number_entry; ++i)
   	{
   		// Get info about current file.
   		unz_file_info file_info;
   		char filename[MAX_FILENAME];
   		if (unzGetCurrentFileInfo(zipfile, &file_info, filename, MAX_FILENAME, NULL, 0, NULL, 0) != UNZ_OK)
   		{
   			LOGD("could not read file info\n");
   			unzClose(zipfile);
   			zk_display_deinit();
   			return false;
   		}

   		LOGD("filesize cs:%d, us:%d\n", file_info.compressed_size, file_info.uncompressed_size);

   		// Check if this entry is a directory or file.
   		const size_t filename_length = strlen(filename);
   		if (filename[filename_length-1] == DIE_DELIMTER)
   		{
   			// Entry is a directory.
   			LOGD("dir:%s\n", filename);
   		}
   		else if(strstr(filename,"preview") > 0){
   			LOGD("previewfile:%s\n", filename);
   		}
   		else if (str_ends_with(filename, ".png"))
   		{
   			// Entry is a file, so extract it.
   			LOGD("file:%s\n", filename);
   			if (unzOpenCurrentFile(zipfile) != UNZ_OK)
   			{
   				LOGD("could not open file: %s\n", filename);
   				unzClose(zipfile);
   	   			zk_display_deinit();
   				return false;
   			}

   			LOGD("extract file:%s\n", filename);

   			int error = UNZ_OK;
   			unsigned char* read_buf = (unsigned char*)malloc(file_info.uncompressed_size);
   			error = unzReadCurrentFile(zipfile, read_buf, file_info.uncompressed_size);
   			if (error < 0)
   			{
   				LOGD("error %d\n", error);
   				unzCloseCurrentFile(zipfile);
   				unzClose(zipfile);
   				free(read_buf);
   	   			zk_display_deinit();
   				return false;
   			}

   			uint8_t *pData = stbi_load_from_memory(read_buf, file_info.uncompressed_size, &width, &height, &depth, 0);
   			free(read_buf);

   			if (pData) {
   	   			LOGD("width %d, height %d, depth %d\n", width, height, depth);
   				zk_display_draw(pData, width/3, height, 3);
   				stbi_image_free(pData);
   			}
   			//sleep(0.5);
   		}

   		unzCloseCurrentFile(zipfile);

   		// Go the the next entry listed in the zip file.
   		if ((i+1) < global_info.number_entry)
   		{
   			if (unzGoToNextFile(zipfile) != UNZ_OK)
   			{
   				LOGD("cound not read next file\n");
   				unzClose(zipfile);
   	   			zk_display_deinit();
   				return false;
   			}
   		}
   	}
   	unzClose(zipfile);
	zk_display_deinit();
    return 1;
}
